#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GUI主界面模块
FreeNote应用的图形用户界面
"""

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import datetime

from mod_conf import get_config_manager, get_setting, set_setting
from mod_tpl import get_template_help_text
from mod_file import save_note_content, FileSaveError


class FreeNoteApp:
    def __init__(self, root):
        self.root = root
        self.root.title("FreeNote-随手记")
        self.root.geometry("1000x800")

        # 文本修改状态标志
        self.text_modified = False

        # 获取配置管理器
        self.config_manager = get_config_manager()

        # 创建界面
        self.create_widgets()

        # 绑定快捷键
        self.bind_shortcuts()

    def create_widgets(self):
        """创建界面组件"""
        # 初始化界面变量
        self.init_ui_variables()

        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 配置Grid布局权重
        main_frame.grid_rowconfigure(0, weight=0)    # 工具栏：固定高度
        main_frame.grid_rowconfigure(1, weight=1)    # 文本区域：可伸缩
        main_frame.grid_rowconfigure(2, weight=0)    # 状态栏：固定高度
        main_frame.grid_columnconfigure(0, weight=1)  # 列可伸缩

        # 工具栏
        self.create_toolbar(main_frame)

        # 文本编辑区域
        self.create_text_area(main_frame)

        # 状态栏
        self.create_status_bar(main_frame)

    def init_ui_variables(self):
        """初始化界面变量"""
        # 目录变量
        self.folder_var = tk.StringVar(
            value=get_setting('folder'))

        # 文件名变量
        self.filename_var = tk.StringVar(
            value=get_setting('filename'))

        # 扩展名变量
        self.ext_var = tk.StringVar(
            value=get_setting('ext'))

    def create_toolbar(self, parent):
        """创建工具栏"""
        toolbar = ttk.Frame(parent)
        toolbar.grid(row=0, column=0, sticky=tk.EW, pady=(0, 5))

        # 配置grid权重，使目录框和文件名框可以缩放
        toolbar.grid_columnconfigure(0, weight=1)  # 目录框列
        toolbar.grid_columnconfigure(2, weight=2)  # 文件名框列，权重为目录框的2倍

        # 目录框
        self.dir_entry = ttk.Entry(toolbar, textvariable=self.folder_var)
        self.dir_entry.grid(row=0, column=0, sticky=tk.EW, padx=(0, 5))

        # 绑定失去焦点事件
        self.dir_entry.bind('<FocusOut>', self.on_folder_focus_out)
        self.dir_entry.bind('<Return>', self.on_folder_focus_out)

        # 选择目录按钮
        browse_btn = ttk.Button(toolbar, text="选择", width=4, command=self.browse_folder)
        browse_btn.grid(row=0, column=1, padx=(0, 10))

        # 文件名框
        self.filename_entry = ttk.Entry(
            toolbar, textvariable=self.filename_var)
        self.filename_entry.grid(row=0, column=2, sticky=tk.EW, padx=(0, 5))

        # 绑定失去焦点事件
        self.filename_entry.bind('<FocusOut>', self.on_filename_focus_out)
        self.filename_entry.bind('<Return>', self.on_filename_focus_out)

        # 模板按钮
        template_btn = ttk.Button(toolbar, text="模板", width=4, command=self.show_template_help)
        template_btn.grid(row=0, column=3, padx=(0, 10))

        # 扩展名选择框
        ext_combo = ttk.Combobox(toolbar, textvariable=self.ext_var, values=['.txt', '.md'], width=8, state='readonly')
        ext_combo.bind('<<ComboboxSelected>>', self.on_ext_change)
        ext_combo.grid(row=0, column=4, padx=(0, 10))

        # 保存按钮
        save_btn = ttk.Button(toolbar, text="保存", width=4, command=self.save_note)
        save_btn.grid(row=0, column=5)

    def create_text_area(self, parent):
        """创建文本编辑区域"""
        text_frame = ttk.Frame(parent)
        text_frame.grid(row=1, column=0, sticky=tk.NSEW)

        # 配置文本框架的布局权重
        text_frame.grid_rowconfigure(0, weight=1)
        text_frame.grid_columnconfigure(0, weight=1)

        # 文本框
        self.text_area = tk.Text(text_frame, wrap=tk.WORD)
        self.text_area.grid(row=0, column=0, sticky=tk.NSEW)

        # 绑定文本修改事件
        self.text_area.bind('<KeyPress>', self.on_text_modified)
        self.text_area.bind('<KeyRelease>', self.on_text_modified)
        self.text_area.bind('<Button-1>', self.on_text_modified)
        self.text_area.bind('<Control-v>', self.on_text_modified)  # 粘贴
        self.text_area.bind('<Control-x>', self.on_text_modified)  # 剪切

        # 滚动条
        scrollbar = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=self.text_area.yview)
        scrollbar.grid(row=0, column=1, sticky=tk.NS)
        self.text_area.config(yscrollcommand=scrollbar.set)

    def create_status_bar(self, parent):
        """创建状态栏"""
        status_frame = ttk.Frame(parent)
        status_frame.grid(row=2, column=0, sticky=tk.EW, pady=(5, 0))

        # 配置状态栏布局权重
        status_frame.grid_columnconfigure(0, weight=1)  # 左侧状态消息可伸缩
        status_frame.grid_columnconfigure(1, weight=0)  # 右侧尺寸信息固定

        # 主状态消息
        self.status_var = tk.StringVar()
        status_label = ttk.Label(status_frame, textvariable=self.status_var)
        status_label.grid(row=0, column=0, sticky=tk.W)

        # 窗口尺寸信息
        self.size_var = tk.StringVar()
        size_label = ttk.Label(status_frame, textvariable=self.size_var)
        size_label.grid(row=0, column=1, sticky=tk.E)

        # 初始化窗口尺寸显示
        self.update_window_size()

        # 绑定窗口resize事件
        self.root.bind('<Configure>', self.on_window_resize)

    def bind_shortcuts(self):
        """绑定快捷键"""
        self.root.bind('<Control-s>', lambda e: self.save_note())
        self.root.bind('<Control-n>', lambda e: self.clear_text())

    def on_text_modified(self, event=None):
        """文本内容修改时的回调"""
        # 使用after方法延迟检查，确保文本已经更新
        self.root.after_idle(self.check_text_modified)

    def check_text_modified(self):
        """检查文本是否被修改"""
        current_content = self.text_area.get("1.0", tk.END).strip()
        if current_content and not self.text_modified:
            self.text_modified = True
            self.update_title()
        elif not current_content and self.text_modified:
            self.text_modified = False
            self.update_title()

    def update_title(self):
        """更新窗口标题以显示修改状态"""
        base_title = "FreeNote - 随手记录"
        if self.text_modified:
            self.root.title(f"{base_title} *")
        else:
            self.root.title(base_title)

    def reset_modified_flag(self):
        """重置修改标志"""
        self.text_modified = False
        self.update_title()

    def clear_text(self):
        """清空文本框内容"""
        if self.text_modified:
            # 如果文本已修改，询问用户是否确认清空
            if not messagebox.askyesno("确认", "文本内容已修改但未保存，确定要清空吗？"):
                return

        # 清空文本框
        self.text_area.delete("1.0", tk.END)

        # 重置修改标志
        self.reset_modified_flag()

        # 更新状态栏
        self.update_status("文本已清空")

    def on_folder_focus_out(self, event=None):
        """目录框失去焦点时保存配置"""
        new_val = self.folder_var.get().strip()
        old_val = get_setting('folder')

        if new_val and new_val != old_val:
            # 更新配置
            set_setting('folder', new_val)
            self.update_status(f"保存文件夹{new_val}")

    def on_filename_focus_out(self, event=None):
        """文件名框失去焦点时保存配置"""
        new_val = self.filename_var.get().strip()
        old_val = get_setting('filename')

        if new_val and new_val != old_val:
            # 更新配置
            set_setting('filename', new_val)
            self.update_status(f"文件名{new_val}")

    def on_ext_change(self, event=None):
        """扩展名变化时保存配置"""
        new_val = self.ext_var.get().strip()
        old_val = get_setting('ext')

        if new_val and new_val != old_val:
            # 更新配置
            set_setting('ext', new_val)
            self.update_status(f"扩展名已更改为{new_val}")

    def browse_folder(self):
        """浏览选择目录"""
        folder = filedialog.askdirectory(initialdir=self.folder_var.get())
        if folder:
            self.folder_var.set(folder)
            # 触发失去焦点事件来保存配置
            self.on_folder_focus_out()

    def save_note(self):
        """保存笔记"""
        # 检查文本是否被修改
        if not self.text_modified:
            messagebox.showinfo("提示", "文本内容未修改，无需保存。")
            return

        content = self.text_area.get("1.0", tk.END)

        try:
            # 获取参数
            filename_template = self.filename_var.get().strip()
            folder = self.folder_var.get().strip()
            ext = self.ext_var.get().strip()

            # 定义覆盖确认回调
            def overwrite_callback(filepath):
                return messagebox.askyesno("确认", f"文件 {filepath} 已存在，是否覆盖？")

            # 保存文件
            filepath = save_note_content(
                content, filename_template, folder, ext,
                overwrite_callback=overwrite_callback
            )

            # 更新状态
            self.update_status(f"已保存: {filepath}")

            # 重置修改标志
            self.reset_modified_flag()

        except FileSaveError as e:
            messagebox.showerror("错误", str(e))
        except Exception as e:
            messagebox.showerror("错误", f"保存失败: {str(e)}")

    def update_status(self, message):
        """更新状态栏"""
        status_text = f"{datetime.datetime.now().strftime('%H:%M:%S')} - {message}"
        self.status_var.set(status_text)

    def update_window_size(self):
        """更新窗口尺寸显示"""
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        self.size_var.set(f"{width} x {height}")

    def on_window_resize(self, event=None):
        """窗口尺寸变化事件处理"""
        # 只响应主窗口的resize事件，忽略子组件的事件
        if event and event.widget == self.root:
            self.update_window_size()

    def show_template_help(self):
        """显示模板变量帮助"""
        help_text = get_template_help_text()
        messagebox.showinfo("文件名模板帮助", help_text)


def create_app():
    """创建并返回应用程序实例"""
    root = tk.Tk()
    app = FreeNoteApp(root)
    return root, app
